package com.rzico.sbl.ui.manager

import android.Manifest
import android.content.Intent
import android.graphics.Color
import android.graphics.Point
import android.net.Uri
import android.os.Bundle
import android.os.PersistableBundle
import android.provider.Settings
import android.view.MotionEvent
import androidx.activity.result.ActivityResultLauncher
import androidx.lifecycle.lifecycleScope
import com.amap.api.centerLatlng
import com.amap.api.intersection
import com.amap.api.maps.AMap
import com.amap.api.maps.CameraUpdateFactory
import com.amap.api.maps.model.*
import com.amap.api.screenDistance
import com.amap.api.setCameraChangeListener
import com.fondesa.kpermissions.allGranted
import com.fondesa.kpermissions.anyPermanentlyDenied
import com.fondesa.kpermissions.extension.permissionsBuilder
import com.fondesa.kpermissions.extension.send
import com.jeremyliao.liveeventbus.LiveEventBus
import com.rzico.sbl.R
import com.rzico.sbl.databinding.ActivityMasterAreaEditBinding
import com.rzico.sbl.model.BaseUrl
import com.rzico.sbl.model.DrawLatLng
import com.rzico.sbl.viewmodel.MasterViewModel
import com.xinnuo.common.extend.*
import com.xinnuo.common.helper.dp2px
import com.xinnuo.common_ui.base.BaseActivity
import com.xinnuo.common_ui.base.addItems
import com.xinnuo.common_ui.utils.bindLifeCycle
import com.xinnuo.common_ui.utils.showHintDialog
import com.xinnuo.common_ui.utils.showOneHintDialog
import com.xinnuo.common_ui.utils.subscribeBySuccess
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.json.JSONArray
import org.json.JSONObject
import kotlin.math.pow
import kotlin.math.sqrt


class MasterAreaEditActivity : BaseActivity(R.layout.activity_master_area_edit) {

    private val mBinding by lazy { ActivityMasterAreaEditBinding.bind(getRootView()) }

    override fun getViewModel() = get<MasterViewModel>()

    private lateinit var mLauncher: ActivityResultLauncher<Intent>

    private val mDefaultArea by lazy { dp2px(20f) } //marker点击区域

    // 标记点集合
    private val mPointList = arrayListOf<DrawLatLng>()

    // 触摸距离标记点集合
    private val mPointLengthMap = HashMap<Int, Double>()

    // Marker点集合
    private val mMakerList = arrayListOf<Marker>()

    private var mPolyline: Polyline? = null //连接线对象
    private var mPolygon: Polygon? = null   //区域对象
    private var mMapClickEnable: Boolean = true   //地图是否可点击
    private var hasMarkerTouched: Boolean = false //是否触摸标记点
    private var hasDrawFinish: Boolean = false    //是否绘制完成
    private var mMovePosition: Int = -1           //触摸标记点索引
    private var mMoveBigMarker: Boolean = false   //触摸是否是大标记点
    private var mToolbarHeight: Int = 0           //标题栏高度
    private var mDownX: Int = 0  //触摸按下x轴
    private var mDownY: Int = 0  //触摸按下y轴
    private var mMoveX: Int = 0  //触摸移动x轴
    private var mMoveY: Int = 0  //触摸移动y轴

    override fun initData() {
        initTitle(title = "绘制区域")

        mLauncher = requestForResult { initAmap() }

        // 获取标题栏高度
        getToolbar()
            .post {
                mToolbarHeight = getToolbar().measuredHeight
            }

        requestPermission()
    }

    /**
     * 定位权限申请
     */
    private fun requestPermission() {
        permissionsBuilder(
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.ACCESS_FINE_LOCATION
        )
            .build()
            .send {
                when {
                    it.allGranted() -> initAmap()
                    it.anyPermanentlyDenied() -> showPermissionDialog()
                    else -> finishView()
                }
            }
    }

    /**
     * 权限禁止显示后提示操作
     */
    private fun showPermissionDialog() {
        showHintDialog(
            title = "提示",
            hint = "位置权限被禁止开启，请打开权限设置页面手动开启",
            sure = "去设置",
            cancel = "再想想",
            isForced = true,
            onCancel = { finishView() },
            onSure = {
                mLauncher.launch(
                    Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                        .apply {
                            data = Uri.parse("package:$packageName")
                        }
                )
            }
        )
    }

    /**
     * 地图显示初始化
     */
    private fun initAmap() {
        mBinding
            .areaMap
            .map
            .apply {
                uiSettings.apply {
                    isZoomControlsEnabled = false     //缩放按钮，默认打开
                    isCompassEnabled = false          //指南针，默认不显示
                    isMyLocationButtonEnabled = false //定位按钮
                    isScaleControlsEnabled = true     //比例尺
                    isScrollGesturesEnabled = true    //滑动手势
                    isZoomGesturesEnabled = true      //缩放手势
                    isRotateGesturesEnabled = false   //旋转手势
                    isTiltGesturesEnabled = false     //倾斜手势
                    setLogoBottomMargin(-100)         //隐藏logo
                }

                mapType = AMap.MAP_TYPE_NAVI   //导航地图模式
                isTrafficEnabled = false       //实时交通状况
                showBuildings(true)            //显示3D楼块
                showMapText(true)              //显示底图文字
                showIndoorMap(true)            //设置是否显示室内地图
                // 是否触发定位并显示定位层
                isMyLocationEnabled = intent.getExtra("mode") == "add"

                // 定位图层设置
                myLocationStyle = MyLocationStyle().apply {
                    // 定位一次，且将视角移动到地图中心点
                    myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE)
                    strokeColor(Color.TRANSPARENT)     //设置定位蓝点精度圆圈的边框颜色
                    radiusFillColor(Color.TRANSPARENT) //设置定位蓝点精度圆圈的填充颜色
                    showMyLocation(true)               //设置是否显示定位小蓝点
                    // 设置定位蓝点的icon图标方法
                    myLocationIcon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_location_point))
                }

                // 自定义地图
                setCustomMapStyle(
                    CustomMapStyleOptions().apply {
                        isEnable = true
                        styleData = getByteFromAssets("style.data")
                        styleExtraData = getByteFromAssets("style_extra.data")
                    }
                )

                // 设置用户定位信息监听
                setOnMyLocationChangeListener { }

                // 地图加载完成监听
                setOnMapLoadedListener {
                    if (intent.getExtra("mode") == "edit") {
                        mPointList.addItems(
                            intent.getParcelableArrayListExtra("points")
                        )

                        mPointList
                            .forEach {
                                mMakerList.add(
                                    if (it.isBigDot) drawBigMarker(it.latLng)
                                    else drawSmallMarker(it.latLng)
                                )
                            }

                        drawLine()
                        drawPolygon()
                        hasDrawFinish = true

                        lifecycleScope.launch(Dispatchers.IO) {
                            delay(100)

                            // 移动镜头到当前视角
                            val bounds = LatLngBounds
                                .Builder()
                                .apply {
                                    mPointList
                                        .forEach { include(it.latLng) }
                                }
                                .build()

                            withContext(Dispatchers.Main) {
                                mBinding.areaMap.map
                                    .animateCamera(
                                        CameraUpdateFactory
                                            .newLatLngBounds(bounds, 150)
                                    )
                            }
                        }
                    }
                }

                // 地图状态的监听
                setCameraChangeListener { }

                // 地图点击事件监听
                setOnMapClickListener { latLng ->
                    if (mMapClickEnable && !hasMarkerTouched) {
                        if (!hasDrawFinish) {
                            if (mPointList.isEmpty()) {
                                mPointList.add(
                                    DrawLatLng(latLng, true).apply {
                                        mMakerList.add(drawBigMarker(this.latLng))
                                    }
                                )
                            } else {
                                if (!checkMarker(latLng)) {
                                    // 绘制左边小标记点
                                    val pointLeft = centerLatlng(
                                        mPointList.last().latLng,
                                        latLng
                                    )
                                    mMakerList.add(drawSmallMarker(pointLeft))
                                    mPointList.add(DrawLatLng(pointLeft, false))

                                    // 绘制中间大标记点
                                    mMakerList.add(drawBigMarker(latLng))
                                    mPointList.add(DrawLatLng(latLng, true))

                                    // 连线
                                    drawLine()
                                }
                            }
                        }

                        checkMarker(latLng)
                    }
                }

                // marker点击事件监听
                setOnMarkerClickListener { marker ->
                    if (!mMapClickEnable || mPointList.size < 3)
                        return@setOnMarkerClickListener false

                    if (!hasDrawFinish) {
                        if (marker.position.latitude == mPointList[0].latLng.latitude
                            && marker.position.longitude == mPointList[0].latLng.longitude
                        ) {
                            // 绘制右边小标记点
                            val pointLast = centerLatlng(
                                mPointList.last().latLng,
                                mPointList.first().latLng
                            )
                            mMakerList.add(drawSmallMarker(pointLast))
                            mPointList.add(DrawLatLng(pointLast, false))

                            drawPolygon()
                            hasDrawFinish = true
                        }
                    }

                    // 判断marker是否为小标记点
                    mPointList.firstOrNull {
                        !it.isBigDot
                                && marker.position.latitude == it.latLng.latitude
                                && marker.position.longitude == it.latLng.longitude
                    }?.let {
                        drawBigAndSmallMarker(
                            mPointList.indexOf(it),
                            it.latLng
                        )
                    }

                    true
                }

                // POI点击事件监听
                setOnPOIClickListener { poi ->
                    if (mMapClickEnable && !hasDrawFinish) {
                        if (mPointList.isEmpty()) {
                            mPointList.add(
                                DrawLatLng(poi.coordinate, true).apply {
                                    mMakerList.add(drawBigMarker(this.latLng))
                                }
                            )
                        } else {
                            if (mPointList.none {
                                    it.latLng.latitude == poi.coordinate.latitude
                                            && it.latLng.longitude == poi.coordinate.longitude
                                }) {
                                // 绘制左边小标记点
                                val pointLeft = centerLatlng(
                                    mPointList.last().latLng,
                                    poi.coordinate
                                )
                                mMakerList.add(drawSmallMarker(pointLeft))
                                mPointList.add(DrawLatLng(pointLeft, false))

                                // 绘制中间大标记点
                                mMakerList.add(drawBigMarker(poi.coordinate))
                                mPointList.add(DrawLatLng(poi.coordinate, true))

                                // 连线
                                drawLine()
                            }
                        }
                    }
                }

                // moveCamera(CameraUpdateFactory.changeTilt(60f)) //设置地图倾斜度，单位角度，范围（0,60）
                moveCamera(CameraUpdateFactory.zoomTo(14f)) //设置地图缩放级别
                moveCamera(CameraUpdateFactory.newLatLng(LatLng(34.7466, 113.625367))) //默认显示郑州经纬度
            }
    }

    override fun initListener() {
        mBinding.apply {
            areaBack.setOnClickListener { drawCancel() }

            areaDelete.setOnClickListener { drawDelete() }

            areaSure.oneClick {
                when {
                    !hasDrawFinish -> {
                        showToast("请先标记并绘制区域")
                        return@oneClick
                    }
                    checkPolygon() -> {
                        showToast("请检查标记点是否交叉")
                        return@oneClick
                    }
                }

                val jsonArr = JSONArray().apply {

                    mPointList.forEach {
                        put(
                            JSONObject().apply {
                                put("lat", it.latLng.latitude)
                                put("lng", it.latLng.longitude)
                                put("big", if (it.isBigDot) "1" else "0")
                            }
                        )
                    }
                }

                getViewModel()
                    .requestBind(
                        requestUrl = BaseUrl.mngAreaUpe,
                        params = arrayOf(
                            "id" to intent.getExtra("areaId"),
                            "adminId" to intent.getExtra("memberId"),
                            "points" to jsonArr.toString()
                        )
                    )
                    .bindLifeCycle(getLifecycleOwner())
                    .subscribeBySuccess(
                        event = getViewModel(),
                        onSuccess = {
                            showToast("绘制区域成功！")

                            LiveEventBus
                                .get("areaEdit")
                                .post(mPointList)

                            finishView()
                        }
                    )
            }

            areaHint.oneClick {
                showOneHintDialog(
                    title = "绘制方法",
                    hint = getString(R.string.hint_area)
                )
            }
        }
    }

    /**
     * 监听手势滑动
     */
    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        if (mMapClickEnable && mPointList.size > 2) {
            when (ev.action) {
                MotionEvent.ACTION_DOWN -> {
                    mDownX = ev.x.toInt()
                    mDownY = ev.y.toInt()
                    mMoveX = ev.x.toInt()
                    mMoveY = ev.y.toInt()
                }
                MotionEvent.ACTION_MOVE -> {
                    if (mDownY < mToolbarHeight)
                        return super.dispatchTouchEvent(ev)
                    else {
                        if (hasMarkerTouched) {
                            handleMovingEvent(ev)
                        } else {
                            mMoveX = ev.x.toInt()
                            mMoveY = ev.y.toInt()

                            // 触摸移动距离
                            val distance = sqrt(
                                (mDownX - mMoveX).toDouble().pow(2.0)
                                        + (mDownY - mMoveY).toDouble().pow(2.0)
                            )

                            if (distance > dp2px(10f))
                                handleMoveStartEvent(ev)
                        }
                    }
                }
                MotionEvent.ACTION_UP -> handleMoveEndEvent()
            }
        }

        return super.dispatchTouchEvent(ev)
    }

    /**
     * 滑动中处理
     */
    private fun handleMovingEvent(ev: MotionEvent) {
        if (hasDrawFinish) handleDoneEvent(ev)
        else handleNotEvent(ev)
    }

    /**
     * 滑动中未完成绘制处理
     */
    private fun handleNotEvent(ev: MotionEvent) {
        mBinding
            .areaMap
            .map
            .apply {
                val latLng = projection.fromScreenLocation(
                    Point(
                        ev.x.toInt(),
                        ev.y.toInt() - mToolbarHeight
                    )
                )

                // 是否移动大标记点
                if (mMoveBigMarker) {
                    when (mMovePosition) {
                        0 -> { //第一个大标记点
                            // 绘制大标记点
                            mMakerList.removeAt(0).remove()
                            mPointList.removeAt(0)
                            mMakerList.add(0, drawBigMarker(latLng))
                            mPointList.add(0, DrawLatLng(latLng, true))

                            // 绘制右边小标记点
                            val pointRight = centerLatlng(mPointList[2].latLng, latLng)
                            mMakerList.removeAt(1).remove()
                            mPointList.removeAt(1)
                            mMakerList.add(1, drawSmallMarker(pointRight))
                            mPointList.add(1, DrawLatLng(pointRight, false))

                            // 连线
                            drawLine()
                        }
                        mPointList.size - 1 -> { //最后一个大标记点
                            // 绘制左边小标记点
                            val pointLeft =
                                centerLatlng(mPointList[mMovePosition - 2].latLng, latLng)
                            mMakerList.removeAt(mMovePosition - 1).remove()
                            mPointList.removeAt(mMovePosition - 1)
                            mMakerList.add(mMovePosition - 1, drawSmallMarker(pointLeft))
                            mPointList.add(mMovePosition - 1, DrawLatLng(pointLeft, false))

                            // 绘制中间大标记点
                            mMakerList.removeAt(mMovePosition).remove()
                            mPointList.removeAt(mMovePosition)
                            mMakerList.add(mMovePosition, drawBigMarker(latLng))
                            mPointList.add(mMovePosition, DrawLatLng(latLng, true))

                            // 连线
                            drawLine()
                        }
                        else -> { //中间大标记点
                            // 绘制左边小标记点
                            val pointLeft =
                                centerLatlng(mPointList[mMovePosition - 2].latLng, latLng)
                            mMakerList.removeAt(mMovePosition - 1).remove()
                            mPointList.removeAt(mMovePosition - 1)
                            mMakerList.add(mMovePosition - 1, drawSmallMarker(pointLeft))
                            mPointList.add(mMovePosition - 1, DrawLatLng(pointLeft, false))

                            // 绘制中间大标记点
                            mMakerList.removeAt(mMovePosition).remove()
                            mPointList.removeAt(mMovePosition)
                            mMakerList.add(mMovePosition, drawBigMarker(latLng))
                            mPointList.add(mMovePosition, DrawLatLng(latLng, true))

                            // 绘制右边小标记点
                            val pointRight =
                                centerLatlng(mPointList[mMovePosition + 2].latLng, latLng)
                            mMakerList.removeAt(mMovePosition + 1).remove()
                            mPointList.removeAt(mMovePosition + 1)
                            mMakerList.add(mMovePosition + 1, drawSmallMarker(pointRight))
                            mPointList.add(mMovePosition + 1, DrawLatLng(pointRight, false))

                            // 连线
                            drawLine()
                        }
                    }
                } else {
                    // 绘制左边小标记点
                    val pointLeft =
                        centerLatlng(mPointList[mMovePosition - 1].latLng, latLng)
                    mMakerList.removeAt(mMovePosition).remove()
                    mPointList.removeAt(mMovePosition)
                    mMakerList.add(mMovePosition, drawSmallMarker(pointLeft))
                    mPointList.add(mMovePosition, DrawLatLng(pointLeft, false))

                    // 绘制中间大标记点
                    mMakerList.add(mMovePosition + 1, drawBigMarker(latLng))
                    mPointList.add(mMovePosition + 1, DrawLatLng(latLng, true))

                    // 绘制右边小标记点
                    val pointRight =
                        centerLatlng(
                            mPointList[mMovePosition + 1].latLng,
                            mPointList[mMovePosition + 2].latLng
                        )
                    mMakerList.add(mMovePosition + 2, drawSmallMarker(pointRight))
                    mPointList.add(mMovePosition + 2, DrawLatLng(pointRight, false))

                    // 连线
                    drawLine()

                    mMovePosition += 1
                    mMoveBigMarker = true
                }
            }
    }

    /**
     * 滑动中已完成绘制处理
     */
    private fun handleDoneEvent(ev: MotionEvent) {
        mBinding
            .areaMap
            .map
            .apply {
                val latLng = projection.fromScreenLocation(
                    Point(
                        ev.x.toInt(),
                        ev.y.toInt() - mToolbarHeight
                    )
                )

                // 是否移动大标记点
                if (mMoveBigMarker) {
                    when (mMovePosition) {
                        0 -> { //第一个大标记点
                            // 绘制左边边小标记点
                            val pointLeft =
                                centerLatlng(mPointList[mPointList.size - 2].latLng, latLng)
                            mMakerList.removeLast().remove()
                            mPointList.removeLast()
                            mMakerList.add(drawSmallMarker(pointLeft))
                            mPointList.add(DrawLatLng(pointLeft, false))

                            // 绘制大标记点
                            mMakerList.removeAt(0).remove()
                            mPointList.removeAt(0)
                            mMakerList.add(0, drawBigMarker(latLng))
                            mPointList.add(0, DrawLatLng(latLng, true))

                            // 绘制右边小标记点
                            val pointRight = centerLatlng(mPointList[2].latLng, latLng)
                            mMakerList.removeAt(1).remove()
                            mPointList.removeAt(1)
                            mMakerList.add(1, drawSmallMarker(pointRight))
                            mPointList.add(1, DrawLatLng(pointRight, false))

                            // 绘制区域
                            drawPolygon()
                        }
                        mPointList.size - 2 -> { //最后一个大标记点
                            // 绘制左边小标记点
                            val pointLeft =
                                centerLatlng(mPointList[mMovePosition - 2].latLng, latLng)
                            mMakerList.removeAt(mMovePosition - 1).remove()
                            mPointList.removeAt(mMovePosition - 1)
                            mMakerList.add(mMovePosition - 1, drawSmallMarker(pointLeft))
                            mPointList.add(mMovePosition - 1, DrawLatLng(pointLeft, false))

                            // 绘制中间大标记点
                            mMakerList.removeAt(mMovePosition).remove()
                            mPointList.removeAt(mMovePosition)
                            mMakerList.add(mMovePosition, drawBigMarker(latLng))
                            mPointList.add(mMovePosition, DrawLatLng(latLng, true))

                            // 绘制右边小标记点
                            val pointRight = centerLatlng(mPointList[0].latLng, latLng)
                            mMakerList.removeLast().remove()
                            mPointList.removeLast()
                            mMakerList.add(drawSmallMarker(pointRight))
                            mPointList.add(DrawLatLng(pointRight, false))

                            // 绘制区域
                            drawPolygon()
                        }
                        else -> { //中间大标记点
                            // 绘制左边小标记点
                            val pointLeft =
                                centerLatlng(mPointList[mMovePosition - 2].latLng, latLng)
                            mMakerList.removeAt(mMovePosition - 1).remove()
                            mPointList.removeAt(mMovePosition - 1)
                            mMakerList.add(mMovePosition - 1, drawSmallMarker(pointLeft))
                            mPointList.add(mMovePosition - 1, DrawLatLng(pointLeft, false))

                            // 绘制中间大标记点
                            mMakerList.removeAt(mMovePosition).remove()
                            mPointList.removeAt(mMovePosition)
                            mMakerList.add(mMovePosition, drawBigMarker(latLng))
                            mPointList.add(mMovePosition, DrawLatLng(latLng, true))

                            // 绘制右边小标记点
                            val pointRight =
                                centerLatlng(mPointList[mMovePosition + 2].latLng, latLng)
                            mMakerList.removeAt(mMovePosition + 1).remove()
                            mPointList.removeAt(mMovePosition + 1)
                            mMakerList.add(mMovePosition + 1, drawSmallMarker(pointRight))
                            mPointList.add(mMovePosition + 1, DrawLatLng(pointRight, false))

                            // 绘制区域
                            drawPolygon()
                        }
                    }
                } else {
                    when (mMovePosition) {
                        // 最后一个小标记点
                        mPointList.size - 1 -> {
                            // 绘制左边小标记点
                            val pointLeft =
                                centerLatlng(mPointList[mMovePosition - 1].latLng, latLng)
                            mMakerList.removeAt(mMovePosition).remove()
                            mPointList.removeAt(mMovePosition)
                            mMakerList.add(mMovePosition, drawSmallMarker(pointLeft))
                            mPointList.add(mMovePosition, DrawLatLng(pointLeft, false))

                            // 绘制中间大标记点
                            mMakerList.add(drawBigMarker(latLng))
                            mPointList.add(DrawLatLng(latLng, true))

                            // 绘制右边小标记点
                            val pointRight = centerLatlng(mPointList[0].latLng, latLng)
                            mMakerList.add(drawSmallMarker(pointRight))
                            mPointList.add(DrawLatLng(pointRight, false))

                            mMovePosition += 1
                            mMoveBigMarker = true

                            // 绘制区域
                            drawPolygon()
                        }
                        else -> {
                            // 绘制左边小标记点
                            val pointLeft =
                                centerLatlng(mPointList[mMovePosition - 1].latLng, latLng)
                            mMakerList.removeAt(mMovePosition).remove()
                            mPointList.removeAt(mMovePosition)
                            mMakerList.add(mMovePosition, drawSmallMarker(pointLeft))
                            mPointList.add(mMovePosition, DrawLatLng(pointLeft, false))

                            // 绘制中间大标记点
                            mMakerList.add(mMovePosition + 1, drawBigMarker(latLng))
                            mPointList.add(mMovePosition + 1, DrawLatLng(latLng, true))

                            // 绘制右边小标记点
                            val pointRight =
                                centerLatlng(
                                    mPointList[mMovePosition + 1].latLng,
                                    mPointList[mMovePosition + 2].latLng
                                )
                            mMakerList.add(mMovePosition + 2, drawSmallMarker(pointRight))
                            mPointList.add(mMovePosition + 2, DrawLatLng(pointRight, false))

                            mMovePosition += 1
                            mMoveBigMarker = true

                            // 绘制区域
                            drawPolygon()
                        }
                    }
                }
            }
    }

    /**
     * 滑动开始处理
     */
    private fun handleMoveStartEvent(ev: MotionEvent) {
        mPointLengthMap.clear()

        mPointList.forEachIndexed { index, drawLatLng ->
            val point = mBinding
                .areaMap
                .map
                .projection
                .toScreenLocation(drawLatLng.latLng)

            mPointLengthMap[index] =
                sqrt(
                    (ev.x - point.x).toDouble().pow(2.0)
                            + (ev.y - point.y - mToolbarHeight).toDouble().pow(2.0)
                )
        }

        if (mPointLengthMap.isNotEmpty()) {
            val entry = mPointLengthMap.minBy { it.value }

            // 是否触摸标记点
            if (entry.value < mDefaultArea) {
                hasMarkerTouched = true

                mBinding
                    .areaMap
                    .map.uiSettings
                    .setAllGesturesEnabled(false)

                mMovePosition = entry.key
                mMoveBigMarker = mPointList[mMovePosition].isBigDot
            }
        }
    }

    /**
     * 滑动结束处理
     */
    private fun handleMoveEndEvent() {
        hasMarkerTouched = false
        mMovePosition = -1
        mMoveBigMarker = false

        mBinding
            .areaMap
            .map
            .uiSettings
            .apply {
                setAllGesturesEnabled(true)
                isRotateGesturesEnabled = false
                isTiltGesturesEnabled = false
            }
    }

    /**
     * 判断是否点击 marker
     */
    private fun checkMarker(latLng: LatLng): Boolean {
        mPointList.forEachIndexed { index, point ->
            if (!point.isBigDot) {
                val distance = mBinding
                    .areaMap
                    .map
                    .screenDistance(point.latLng, latLng)

                if (distance < mDefaultArea) {
                    drawBigAndSmallMarker(index, point.latLng)
                    return true
                }
            }
        }

        return false
    }

    /**
     * 绘制大标记maker点
     */
    private fun drawBigMarker(latLng: LatLng) =
        mBinding
            .areaMap
            .map
            .addMarker(
                MarkerOptions()
                    .icon(
                        BitmapDescriptorFactory
                            .fromView(inflate(R.layout.layout_marker_area))
                    )
                    .anchor(0.5f, 0.5f)
                    .position(latLng)
            )

    /**
     * 绘制小标记maker点
     */
    private fun drawSmallMarker(latLng: LatLng) =
        mBinding
            .areaMap
            .map
            .addMarker(
                MarkerOptions()
                    .icon(
                        BitmapDescriptorFactory
                            .fromView(inflate(R.layout.layout_marker_area_small))
                    )
                    .anchor(0.5f, 0.5f)
                    .position(latLng)
            )

    /**
     * 绘制一个大两个小标记marker点
     */
    private fun drawBigAndSmallMarker(index: Int, latLng: LatLng) {
        mBinding
            .areaMap
            .map
            .apply {
                // 是否为最后一个标记点
                if (index == mPointList.size - 1) {
                    // 绘制左边小标记点
                    val pointLeft = centerLatlng(
                        mPointList[index - 1].latLng,
                        mPointList[index].latLng
                    )
                    mMakerList.add(index, drawSmallMarker(pointLeft))
                    mPointList.add(index, DrawLatLng(pointLeft, false))

                    // 绘制中间大标记点
                    mMakerList.removeAt(index + 1).remove()
                    mPointList.removeAt(index + 1)
                    mMakerList.add(index + 1, drawBigMarker(latLng))
                    mPointList.add(index + 1, DrawLatLng(latLng, true))

                    // 绘制右边小标记点
                    val pointRight = centerLatlng(
                        mPointList[index + 1].latLng,
                        mPointList[0].latLng
                    )
                    mMakerList.add(drawSmallMarker(pointRight))
                    mPointList.add(DrawLatLng(pointRight, false))
                } else {
                    // 绘制左边小标记点
                    val pointLeft = centerLatlng(
                        mPointList[index - 1].latLng,
                        mPointList[index].latLng
                    )
                    mMakerList.add(index, drawSmallMarker(pointLeft))
                    mPointList.add(index, DrawLatLng(pointLeft, false))

                    // 绘制中间大标记点
                    mMakerList.removeAt(index + 1).remove()
                    mPointList.removeAt(index + 1)
                    mMakerList.add(index + 1, drawBigMarker(latLng))
                    mPointList.add(index + 1, DrawLatLng(latLng, true))

                    // 绘制右边小标记点
                    val pointRight = centerLatlng(
                        mPointList[index + 1].latLng,
                        mPointList[index + 2].latLng
                    )
                    mMakerList.add(index + 2, drawSmallMarker(pointRight))
                    mPointList.add(index + 2, DrawLatLng(pointRight, false))
                }
            }
    }

    /**
     * 绘制连线，把所有点连起来
     */
    private fun drawLine() {
        mPolygon?.remove()  //清除区域
        mPolyline?.remove() //清除连线

        mPointList.notEmpty {
            mPolyline = mBinding.areaMap.map.addPolyline(
                PolylineOptions()
                    .addAll(mPointList.map { it.latLng })
                    .width(8f)
                    .color(Color.parseColor("#2486F8"))
                    .zIndex(999f)
            )
        }
    }

    /**
     * 绘制多边形
     */
    private fun drawPolygon() {
        mPolyline?.remove() //清除连线
        mPolygon?.remove()  //清除区域

        mPolygon = mBinding.areaMap.map.addPolygon(
            PolygonOptions()
                .addAll(mPointList.map { it.latLng })
                .strokeWidth(2f)
                .strokeColor(getColorEx(R.color.transparent))
                .fillColor(
                    getColorEx(if (checkPolygon()) R.color.red50 else R.color.black60)
                )
                .zIndex(100f)
        )
    }

    /**
     * 撤销返回上一步
     */
    private fun drawCancel() {
        if (hasDrawFinish) {
            mMakerList.removeLast().remove()
            mPointList.removeLast()
            hasDrawFinish = false
        } else {
            mMakerList.notEmpty {
                // 删除最后一个标记点
                removeLast().remove()
                mPointList.removeLast()

                // 删除倒数第二个标记点
                if (size > 1) {
                    removeLast().remove()
                    mPointList.removeLast()
                }
            }
        }

        // 连线
        drawLine()
    }

    /**
     * 取消绘制
     */
    private fun drawDelete() {
        mMakerList.onEach { it.remove() }
        mMakerList.clear()
        mPointList.clear()

        mPolyline?.remove()
        mPolygon?.remove()

        hasDrawFinish = false
    }

    /**
     * 判断多边形是否重合
     */
    private fun checkPolygon(): Boolean {
        mBinding.areaMap.map.apply {
            for (i in 0 until mPointList.size - 2) {
                var point3: Point
                var point4: Point
                var flag: Boolean

                val point1 = projection.toScreenLocation(mPointList[i].latLng)
                val point2 = projection.toScreenLocation(mPointList[i + 1].latLng)

                for (j in i + 2 until mPointList.size) {
                    when {
                        i == 0 && j == mPointList.size - 1 -> break
                        j == mPointList.size - 1 -> {
                            point3 = projection.toScreenLocation(mPointList[j].latLng)
                            point4 = projection.toScreenLocation(mPointList[0].latLng)
                            flag = intersection(point1, point2, point3, point4)
                        }
                        else -> {
                            point3 = projection.toScreenLocation(mPointList[j].latLng)
                            point4 = projection.toScreenLocation(mPointList[j + 1].latLng)
                            flag = intersection(point1, point2, point3, point4)
                        }
                    }

                    if (flag) return true
                }
            }
            return false
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // onCreate时执行mMapView.onCreate(savedInstanceState)，创建地图
        mBinding.areaMap.onCreate(savedInstanceState)
    }

    override fun onSaveInstanceState(outState: Bundle, outPersistentState: PersistableBundle) {
        super.onSaveInstanceState(outState, outPersistentState)
        // onSaveInstanceState时执行mMapView.onSaveInstanceState (outState)，保存地图当前的状态
        mBinding.areaMap.onSaveInstanceState(outState)
    }

    override fun onResume() {
        super.onResume()
        // onResume时执行mMapView.onResume ()，重新绘制加载地图
        mBinding.areaMap.onResume()
    }

    override fun onPause() {
        super.onPause()
        // onPause时执行mMapView.onPause ()，暂停地图的绘制
        mBinding.areaMap.onPause()
    }

    override fun onDestroy() {
        super.onDestroy()
        // onDestroy时执行mMapView.onDestroy()，销毁地图
        mBinding.areaMap.onDestroy()
    }

}